package com.kingdee.eas.cp.bc.travel;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.ui.ModelMap;

import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.BOSException;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.bos.eventbus.event.action.KDActionEvent;
import com.kingdee.bos.web.components.util.JsonUtil;
import com.kingdee.bos.webframework.exception.WafException;
import com.kingdee.bos.webframework.json.JSONUtils;
import com.kingdee.bos.webframework.dynamic.application.WebSymbolConstant;
import com.kingdee.bos.webframework.dynamic.handler.AbstractWebEventHandler;
import com.kingdee.bos.eventbus.event.action.IActionEventHandler;
import com.kingdee.bos.metadata.entity.EntityViewInfo;
import com.kingdee.bos.metadata.entity.FilterInfo;
import com.kingdee.bos.metadata.entity.FilterItemInfo;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.eas.basedata.assistant.ExchangeRateInfo;
import com.kingdee.eas.basedata.org.CompanyOrgUnitFactory;
import com.kingdee.eas.basedata.org.CompanyOrgUnitInfo;
import com.kingdee.eas.cp.bc.BizCollUtil;
import com.kingdee.eas.cp.bc.DailyLoanBillInfo;
import com.kingdee.eas.cp.bc.TravelAccountBill;
import com.kingdee.eas.cp.bc.TravelAccountBillInfo;
import com.kingdee.eas.custom.basedata.EvectionSubsiCollection;
import com.kingdee.eas.custom.basedata.EvectionSubsiFactory;
import com.kingdee.eas.custom.basedata.EvectionSubsiInfo;
import com.kingdee.eas.custom.basedata.LodgingCostCollection;
import com.kingdee.eas.custom.basedata.LodgingCostFactory;
import com.kingdee.eas.custom.basedata.LodgingCostInfo;
import com.kingdee.eas.custom.basedata.inlandForeign;
import com.kingdee.eas.custom.basedata.timeIimit;

public class TravelVerifyHandler extends AbstractWebEventHandler implements IActionEventHandler {
	public void onAction(KDActionEvent event) throws WafException,BOSException {
		Map<String, Object> map=new HashMap<String, Object>();
		boolean result=true;
		String msg="";
		try{
			String data=event.getReqeustContext().getHttpServletRequest().getParameter("data");
			String applierCompanyId=event.getReqeustContext().getHttpServletRequest().getParameter("applierCompanyId");
			JSONObject json=JSONObject.parseObject(data);
			Date startDate=json.getDate("startDate"); //出发时间
	 		Date endDate=json.getDate("endDate");  //到达时间
			if(null!=startDate&&null!=endDate){
				if(null==json.get("putUpDay")){
					throw new WafException("住宿天数不能为空!");
				}
				
				if(null==json.get("subsidyDay")){
					throw new WafException("补贴天数不能为空!");
				}
				
				long day=(endDate.getTime()-startDate.getTime())/(24*60*60*1000L)+1; //出差天数
				long putUpDay=json.getLongValue("putUpDay"); //住宿天数
				long subsidyDay=json.getLongValue("subsidyDay"); //补贴天数
				if(putUpDay>(day-1)){
					throw new WafException("住宿天数不能超过(到达日期-出发日期+1)的天数!");
				}
				
				if(subsidyDay>day){
					throw new WafException("补贴天数不能超过(到达日期-出发日期+1)的天数!");
				}
				
				String to=json.getString("to");  //到达城市
				if(null!=to&&!"".equals(to)){
					String isTimeIimit="";
					if(day<=30){
						isTimeIimit = timeIimit.FTRUE_VALUE;
					}else if(day>30&&day<90){
						isTimeIimit = timeIimit.A_VALUE;
					}else{
						isTimeIimit = timeIimit.B_VALUE;
					}
					
					BigDecimal limit = new BigDecimal("0");
					//国外大于30天不校验住宿标准
					if(!isTimeIimit.equals(timeIimit.FTRUE_VALUE)&&json.getString("inlandForeign").equals(inlandForeign.FOREIGN_VALUE)){
					}else{
						EntityViewInfo view=new EntityViewInfo();
						FilterInfo filter=new FilterInfo();
						//获取住宿费标准
						filter.getFilterItems().add(new FilterItemInfo("city",to));
						if(json.getString("inlandForeign").equals(inlandForeign.INLAND_VALUE)){ //国内区分淡旺季和职务等级
							filter.getFilterItems().add(new FilterItemInfo("dutyGrade",json.getString("duty")));
						}
						filter.getFilterItems().add(new FilterItemInfo("inlandForeign",json.getString("inlandForeign")));
						view.setFilter(filter);
						LodgingCostCollection lcc=LodgingCostFactory.getRemoteInstance().getLodgingCostCollection(view);
						LodgingCostInfo lci=new LodgingCostInfo();
						if(lcc.size()>0){
							if(json.getString("inlandForeign").equals(inlandForeign.INLAND_VALUE)){ 
								SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
								Date checkInDate=startDate;
								Date checkOutDate=endDate;
								
								if(null!=json.getDate("checkInDate")){
									checkInDate=json.getDate("checkInDate"); //入住日期
									checkOutDate=json.getDate("checkOutDate"); //退房日期
								}
								
								Calendar start = Calendar.getInstance();
								start.setTime(checkInDate);
								int startYear=start.get(Calendar.YEAR);  //入住日期 年
								
								Calendar end = Calendar.getInstance();
								end.setTime(checkOutDate);
								int endYear=end.get(Calendar.YEAR);  //退房日期 年
								end.set(Calendar.DATE,end.get(Calendar.DATE)-1);
								checkOutDate=sf.parse(sf.format(end.getTime()));
								
								Date checkInDate1=null;
								Date checkOutDate1=null;
								Date checkInDate2=null;
								Date checkOutDate2=null;
								//当然入住和退房日期跨年后，按年做拆分处理
								if(startYear<endYear){
									checkInDate1=checkInDate;
									checkOutDate1=sf.parse(startYear+"-12-31 00:00:00");
									checkInDate2=sf.parse(endYear+"-01-01 00:00:00");
									checkOutDate2=checkOutDate;
								}else{
									checkInDate1=checkInDate;
									checkOutDate1=checkOutDate;
								}
								for(int i=0;i<lcc.size();i++){
									LodgingCostInfo info=lcc.get(i);

									BigDecimal rate = new BigDecimal("1.00");
									CompanyOrgUnitInfo applierCompany = CompanyOrgUnitFactory.getRemoteInstance().getCompanyOrgUnitInfo(new ObjectUuidPK(applierCompanyId));
									ExchangeRateInfo exchangeRate = BizCollUtil.getExRateInfo(info.getCurren().getId().toString(), null, applierCompany, new Date());
									if (exchangeRate != null) {
										rate = exchangeRate.getConvertRate();
									}
									
//									Date startDate=json.getDate("startDate"); //出发时间
//							 		Date endDate=json.getDate("endDate");  //到达时间
//									(endDate>='2018-7-15' and beginDate<='2018-06-30')  #不跨季
//									(endDate>='2018-08-30' and beginDate<='2018-10-15') #跨季
									String beginMonth=info.getMonthOne().getValue();  //开始月
									String beginDay=info.getSunOne().getValue(); //开始日
									String endMonth=info.getMonthTow().getValue();  //结束月
									String endDay=info.getSunTow().getValue(); //结束日
									
									Date standardBegin=sf.parse(startYear+"-"+beginMonth+"-"+beginDay+" 00:00:00"); //标准开始时间
									Date standardend=sf.parse(startYear+"-"+endMonth+"-"+endDay+" 00:00:00"); //标准结束时间
									
									if(putUpDay<=(day-1)){ //住宿天数小于出差天数并且出差天数在一个住宿标准内
										if(standardend.getTime()>=endDate.getTime()&&standardBegin.getTime()<=startDate.getTime()){
											long num=putUpDay;
											limit=limit.add(info.getLimit().multiply(rate).multiply(new BigDecimal(num))); //住宿标准*汇率*住宿天数
											break;
										}
									}
									
									if(standardend.getTime()>=checkOutDate1.getTime()&&standardBegin.getTime()<=checkInDate1.getTime()){
										//不跨季
										long num=putUpDay;
										if(null!=checkInDate2){//跨年
											num=(checkOutDate1.getTime()-checkInDate1.getTime())/(24*60*60*1000);
										}
										
										limit=limit.add(info.getLimit().multiply(rate).multiply(new BigDecimal(num))); //住宿标准*汇率*住宿天数
									}else if(standardend.getTime()>=checkInDate1.getTime()&&standardBegin.getTime()<=checkOutDate1.getTime()){
										//跨季  获取符合跨季的时间，并计算出差时间在季节中有多少天
										//and beginDate<='2018-5-15' and endDate<='2018-10-15'
										//and beginDate>='2018-5-15' and endDate>='2018-10-15'
										//and beginDate>='2018-6-15' and endDate<='2018-10-15'
										long num=0L;
										if(standardBegin.getTime()<=checkInDate1.getTime()&&standardend.getTime()<=checkOutDate1.getTime()){
											num=(standardend.getTime()-checkInDate1.getTime())/(24*60*60*1000)+1;
										}else if(standardBegin.getTime()>=checkInDate1.getTime()&&standardend.getTime()>=checkOutDate1.getTime()){
											num=(checkOutDate1.getTime()-standardBegin.getTime())/(24*60*60*1000)+1;
										}else if(standardBegin.getTime()>=checkInDate1.getTime()&&standardend.getTime()<=checkOutDate1.getTime()){
											num=(standardend.getTime()-standardBegin.getTime())/(24*60*60*1000)+1;
										}
										limit=limit.add(info.getLimit().multiply(rate).multiply(new BigDecimal(num))); //住宿标准*汇率*住宿天数
									}
									
									if(null!=checkInDate2){
										Date standardBegin2=sf.parse(endYear+"-"+beginMonth+"-"+beginDay+" 00:00:00"); //标准开始时间
										Date standardend2=sf.parse(endYear+"-"+endMonth+"-"+endDay+" 00:00:00"); //标准开始时间
										//如果跨年将出差时间按年拆分处理
										if(standardend2.getTime()>=checkOutDate2.getTime()&&standardBegin2.getTime()<=checkInDate2.getTime()){
											//不跨季
											long num=(checkOutDate2.getTime()-checkInDate2.getTime())/(24*60*60*1000)+1;
											limit=limit.add(info.getLimit().multiply(rate).multiply(new BigDecimal(num))); //住宿标准*汇率*住宿天数
										}else if(standardend2.getTime()>=checkInDate2.getTime()&&standardBegin2.getTime()<=checkOutDate2.getTime()){
											//跨季
											long num=0L;
											if(standardBegin.getTime()<=checkInDate1.getTime()&&standardend.getTime()<=checkOutDate1.getTime()){
												num=(standardend.getTime()-checkInDate1.getTime())/(24*60*60*1000)+1;
											}else if(standardBegin.getTime()>=checkInDate1.getTime()&&standardend.getTime()>=checkOutDate1.getTime()){
												num=(checkOutDate1.getTime()-standardBegin.getTime())/(24*60*60*1000)+1;
											}else if(standardBegin.getTime()>=checkInDate1.getTime()&&standardend.getTime()<=checkOutDate1.getTime()){
												num=(standardend.getTime()-standardBegin.getTime())/(24*60*60*1000)+1;
											}
											limit=limit.add(info.getLimit().multiply(rate).multiply(new BigDecimal(num))); //住宿标准*汇率*住宿天数
										}
									}
								}
							}else{
								lci=lcc.get(0);
								
								//获取住宿费标准汇率
								BigDecimal rate = new BigDecimal("1.00");
								CompanyOrgUnitInfo applierCompany = CompanyOrgUnitFactory.getRemoteInstance().getCompanyOrgUnitInfo(new ObjectUuidPK(applierCompanyId));
								ExchangeRateInfo exchangeRate = BizCollUtil.getExRateInfo(lci.getCurren().getId().toString(), null, applierCompany, new Date());
								if (exchangeRate != null) {
									rate = exchangeRate.getConvertRate();
								}
								limit = lci.getLimit().multiply(rate).multiply(new BigDecimal(putUpDay)); //住宿标准*汇率*住宿天数
							}
							
							BigDecimal hotelExpense=json.getBigDecimal("hotelExpense").multiply(json.getBigDecimal("hotelRate"));  //住宿费*汇率
							if(limit.compareTo(hotelExpense)<0){
								throw new WafException("报销的住宿费大于标准金额,请重新填写!");
							}
							
						}else{
							throw new WafException("未找到到达城市的住宿费标准,请先维护住宿费标准!");
						}
						
					}
					//获取出差补贴标准
					EntityViewInfo view = new EntityViewInfo();
					FilterInfo filter = new FilterInfo();
					filter.getFilterItems().add(new FilterItemInfo("city",to));
					filter.getFilterItems().add(new FilterItemInfo("inlandForeign",json.getString("inlandForeign")));
					if(json.getString("inlandForeign").equals(inlandForeign.FOREIGN_VALUE)){
						filter.getFilterItems().add(new FilterItemInfo("timeIimit",isTimeIimit));
						if(!isTimeIimit.equals(timeIimit.FTRUE_VALUE)){ //30天以外
							filter.getFilterItems().add(new FilterItemInfo("dutyTitle",json.getString("jobName")));
						}
					}
					view.setFilter(filter);
					EvectionSubsiCollection esc=EvectionSubsiFactory.getRemoteInstance().getEvectionSubsiCollection(view);
					if(esc.size()>0){
						/*EvectionSubsiInfo esi=esc.get(0);
						
						//获取出差补贴标准汇率
						BigDecimal rate = new BigDecimal("1.00");
						CompanyOrgUnitInfo applierCompany = CompanyOrgUnitFactory.getRemoteInstance().getCompanyOrgUnitInfo(new ObjectUuidPK(applierCompanyId));
						ExchangeRateInfo exchangeRate = BizCollUtil.getExRateInfo(esi.getCurrency().getId().toString(), null, applierCompany, new Date());
						if (exchangeRate != null) {
							rate = exchangeRate.getConvertRate();
						}
						
						BigDecimal foodSubsidy=json.getBigDecimal("foodSubsidy").multiply(json.getBigDecimal("fsReta")); //伙食补贴*汇率
						BigDecimal trafficSubsidy=json.getBigDecimal("trafficSubsidy").multiply(json.getBigDecimal("tsReta")); //交通补贴*汇率
						BigDecimal publicFees=json.getBigDecimal("publicFees").multiply(json.getBigDecimal("pfReta")); //公杂费补贴*汇率
						BigDecimal lifeSubsidy=json.getBigDecimal("lifeSubsidy").multiply(json.getBigDecimal("lifeSubsidyReta"));  //生活补贴*汇率
						String isInlandForeign=json.getString("inlandForeign");
						if(isInlandForeign.equals(inlandForeign.FOREIGN_VALUE)){ //国外
							if(!isTimeIimit.equals(timeIimit.FTRUE_VALUE)){ //30天以外
								
								//报销费用标准30已上  月补贴/30*补贴天数*汇率
								BigDecimal standard=esi.getSubsidy().divide(new BigDecimal(30),2, BigDecimal.ROUND_HALF_UP).multiply(rate).multiply(new BigDecimal(subsidyDay)); 
								if(standard.compareTo(lifeSubsidy)<0){
									throw new WafException("报销的出差补助大于标准金额,请重新填写!");
								}
							}else{ //30天以内
								BigDecimal mealsSubsidy=esi.getMealsSubsidy().multiply(rate).multiply(new BigDecimal(subsidyDay)); //伙食补贴标准*汇率*补贴天数
								BigDecimal affairSubsidy=esi.getAffairSubsidy().multiply(rate).multiply(new BigDecimal(subsidyDay)); //公杂费补贴标准*汇率*补贴天数
								if(mealsSubsidy.compareTo(foodSubsidy)<0){
									throw new WafException("报销的伙食补贴大于标准金额,请重新填写!");
								}
								if(affairSubsidy.compareTo(publicFees)<0){
									throw new WafException("报销的公杂费补贴大于标准金额,请重新填写!");
								}
							}
						}else if(isInlandForeign.equals(inlandForeign.INLAND_VALUE)){ //国内
							BigDecimal mealsSubsidy=esi.getMealsSubsidy().multiply(rate).multiply(new BigDecimal(subsidyDay)); //伙食补贴标准*汇率*补贴天数
							BigDecimal trafficLimit=esi.getTrafficSubsidy().multiply(rate).multiply(new BigDecimal(subsidyDay)); //交通补贴标准*汇率*补贴天数
							if(mealsSubsidy.compareTo(foodSubsidy)<0){
								throw new WafException("报销的伙食补贴大于标准金额,请重新填写!");
							}
							if(trafficLimit.compareTo(trafficSubsidy)<0){
								throw new WafException("报销的交通费补贴大于标准金额,请重新填写!");
							}
						}*/
					}else{
						throw new WafException("未找到到达城市的出差补助标准,请先维出差补助标准!");
					}
				}
			}
		}catch (Exception e) {
			msg=e.getMessage();
			result=false;
		}
		map.put("result", result);
		map.put("msg", msg);
		JSONUtils.SUCCESS(map);
	}
}